/**
  \file wordbuf.c
  \author Francis Girard
  \date 6 march 2012
  
  Word buffer.
*/

/*
 *  Copyright (C) 2012, Francis Girard
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "wordbuf.h"
#include <stdlib.h>


#ifdef WIN32
#pragma warning(disable : 4996)
#endif

typedef struct _WordBuf
{
  char* pWordBegin;
  char* pWordEnd;
  char* pBufEnd;
} WordBuf;

typedef WordBuf* _H_WordBuf;


/**
*/
H_WordBuf WordBuf_Create(unsigned int nInitialSize)
{
  _H_WordBuf hBuf = (_H_WordBuf) malloc(sizeof(WordBuf));
  
  if (nInitialSize == 0)
    nInitialSize = 256;
  
  hBuf->pWordBegin = (char*) malloc(sizeof(char) * nInitialSize);
  hBuf->pWordEnd = hBuf->pWordBegin;
  *(hBuf->pWordEnd) = '\0';
  hBuf->pBufEnd = hBuf->pWordBegin + (nInitialSize - 1);
  
  return (H_WordBuf) hBuf;
}


/**
*/
void WordBuf_Destroy(H_WordBuf hBuf)
{
  free(((_H_WordBuf)hBuf)->pWordBegin);
  free(((_H_WordBuf)hBuf));
}


/**
*/
void WordBuf_Append(H_WordBuf hBuf, char cLetter)
{
  _H_WordBuf hBuf_ = (_H_WordBuf) hBuf;
  if (hBuf_->pWordEnd == hBuf_->pBufEnd)
  {
    unsigned int nLen = hBuf_->pWordEnd - hBuf_->pWordBegin;
    unsigned int nNewSize = ((hBuf_->pBufEnd - hBuf_->pWordBegin) + 1) * 2;
    hBuf_->pWordBegin = (char*) realloc(hBuf_->pWordBegin,
                                        nNewSize * sizeof(char));
    hBuf_->pWordEnd = hBuf_->pWordBegin + nLen;
    hBuf_->pBufEnd = hBuf_->pWordBegin + (nNewSize - 1);
  }
  
  *(hBuf_->pWordEnd) = cLetter;
  hBuf_->pWordEnd++;
  *(hBuf_->pWordEnd) = '\0';
}


/**
*/
void WordBuf_Pop(H_WordBuf hBuf)
{
  _H_WordBuf hBuf_ = (_H_WordBuf) hBuf;
  hBuf_->pWordEnd--;
  *(hBuf_->pWordEnd) = '\0';
}



/**
*/
const char* WordBuf_GetWord(H_WordBuf hBuf)
{
  return ((_H_WordBuf)hBuf)->pWordBegin;
}


/**
*/
unsigned int WordBuf_GetSize(H_WordBuf hBuf)
{
  _H_WordBuf hBuf_ = (_H_WordBuf) hBuf;
  return hBuf_->pWordEnd - hBuf_->pWordBegin;
}


/**
*/
void WordBuf_Clear(H_WordBuf hBuf)
{
  ((_H_WordBuf)hBuf)->pWordEnd = ((_H_WordBuf)hBuf)->pWordBegin;
  ((_H_WordBuf)hBuf)->pWordEnd = '\0';
}

